package com.lds.config.center.client.listener.Annotation;

import com.lds.config.center.client.listener.ItemChangeEvent;
import com.lds.config.center.client.service.ClientService;
import com.lds.config.center.client.service.ClientServiceImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class ItemChangeEventListenerBeanPostProcessor implements BeanPostProcessor {
    private final Set<Class<?>> cache = new HashSet<>();
    private final ClientService clientService = ClientServiceImpl.getInstance();

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class<?> clazz = bean.getClass();
        if (cache.contains(clazz)) return bean;

        // 扫描@ItemChangeEventListener注解
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            ItemChangeEventListener annotation = method.getAnnotation(ItemChangeEventListener.class);
            if (Objects.nonNull(annotation) &&
                    method.getParameterCount() == 1 &&
                    method.getParameters()[0].getType() == ItemChangeEvent.class &&
                    method.getReturnType() == void.class &&
                    method.getModifiers() == Modifier.PUBLIC) {
                clientService.addListener(event -> {
                    try {
                        method.invoke(bean, event);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                });
            }
        }

        cache.add(clazz);
        return bean;
    }
}
